#include "CMainWindow.h"
#include "ui_CMainWindow.h"
#include <QDebug>
#include "VSettings.h"
#include "VAbout.h"
#include <QSizePolicy>
#include "CUIHelper.h"
#include "VDialogProtocal.h"
#include "VDialogAscii.h"
#include "CTableConfig.h"
#include <QToolButton>
#include <QPushButton>
#include "VWindowSplitter.h"
#include <QGraphicsDropShadowEffect>
#ifdef Q_OS_WIN
#include <windows.h>
#endif
#include "CUIHelper.h"
#include "CIconFont.h"
#include "CQssTest.h"
#include <QWidgetAction>
#include "VDialogSkin.h"
#include <QTime>
#include <QFocusEvent>
#include "VToast.h"
#include <QDesktopServices>
#include <QMessageBox>
#include "CPathManager.h"
#include "CTableConfig.h"
#include "VDialogSessionSetting.h"

CMainWindow::CMainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::CMainWindow)
{
    ui->setupUi(this);
    this->setIconSize(QSize(32,32)); //@MAJR 高分屏比较糊
}

CMainWindow::~CMainWindow()
{
    delete ui;
}

CMainWindow *CMainWindow::getInstance()
{
    static CMainWindow *pInstance = nullptr;
    if(nullptr == pInstance) {
        pInstance = new CMainWindow();
    }
    return pInstance;
}

void CMainWindow::init()
{
    //初始化菜单栏
    initMenu();

    //初始化工具栏
    initToolBar();

    //初始化状态栏
    initStatusBar();

    ui->stackedWidget->setCurrentIndex(1);
    //所有会话被关闭 跳转到历史会话
    connect(ui->page_vwindowsplitter,&VWindowSplitter::sigNoSession,this,&CMainWindow::slotShowHistory);

    //选中会话
    connect(ui->page_vwindowsplitter,&VWindowSplitter::sigSelectSession,this,&CMainWindow::slotSelectSession);
    QString strId = CTableConfig::instance()->queryValue(SELECTE_ID);
    hSplitSession(strId); //id为空 默认新建
}

void CMainWindow::hSplitSession(QString strId)
{
    //Id为空是新建 否则是打开
    ui->page_vwindowsplitter->hSplitScreen(strId);
}

void CMainWindow::vSplitSession(QString strId)
{
    //Id为空是新建 否则是打开
    ui->page_vwindowsplitter->vSplitScreen(strId);
}

void CMainWindow::initMenu()
{
    CUIHelper::menuResetStyle(ui->menu_session);
    CUIHelper::menuResetStyle(ui->menu_settings);
    CUIHelper::menuResetStyle(ui->menu_help);

    //为Action 设置图标
    ui->action_h_new->setIcon(CIconFont::getInstance()->pixmap(0xe67a,QSize(16,16)));
    ui->action_v_new->setIcon(CIconFont::getInstance()->pixmap(0xe679,QSize(16,16)));
    ui->menu_history->setIcon(CIconFont::getInstance()->pixmap(0xe699,QSize(16,16)));
    ui->action_save->setIcon(CIconFont::getInstance()->pixmap(0xe6ad,QSize(16,16)));
    ui->action_close_session->setIcon(CIconFont::getInstance()->pixmap(0xe675,QSize(16,16)));
    ui->action_del_session->setIcon(CIconFont::getInstance()->pixmap(0xe668,QSize(16,16)));

    ui->action_preference->setIcon(CIconFont::getInstance()->pixmap(0xe6b2,QSize(16,16)));      //首选项
    ui->action_skin->setIcon(CIconFont::getInstance()->pixmap(0xe622,QSize(16,16)));            //皮肤

    ui->action_about->setIcon(CIconFont::getInstance()->pixmap(0xe6a9,QSize(16,16)));           //关于
    ui->action_ascii->setIcon(CIconFont::getInstance()->pixmap(0xe6bb,QSize(16,16)));           //ASCII
    ui->action_wave->setIcon(CIconFont::getInstance()->pixmap(0xe694,QSize(16,16)));            //波形协议

    connect(ui->menu_session,&QMenu::triggered,[=](QAction *pAction){
        if("action_cache" == pAction->objectName()){
            QString strDataDir = "file:///" + CPathManager::appDataPath();
            QDesktopServices::openUrl(QUrl::fromLocalFile(strDataDir));
        }
    });

    connect(ui->menu_help,&QMenu::triggered,[=](QAction *pAction){
        if("action_about" == pAction->objectName()){
            VAbout vabout;
            vabout.exec();
        }else if("action_wave" == pAction->objectName()){
            VDialogProtocal dialog;
            dialog.exec();
        }else if("action_ascii" == pAction->objectName()){
            VDialogAscii dialog;
            dialog.exec();
        }
    });

    connect(ui->menu_settings,&QMenu::triggered,[=](QAction *pAction){
        if("action_preference" == pAction->objectName()){
            VSettings::getInstance()->show();
        }else if("action_skin" == pAction->objectName()){
            VDialogSkin vdialog(this);
            vdialog.exec();
            //            CQssTest *qssDialog = new CQssTest();
            //            qssDialog->show();
        }
    });

    connect(ui->action_v_new,&QAction::triggered,[=]{
        vSplitSession("");
    });
    connect(ui->action_h_new,&QAction::triggered,[=]{
        hSplitSession("");
    });
    connect(ui->action_close_session,&QAction::triggered,this,&CMainWindow::slotCloseSession);
    connect(ui->action_save,&QAction::triggered,this,&CMainWindow::slotSaveSession);
    connect(ui->action_del_session,&QAction::triggered,this,&CMainWindow::slotRemoveSession);

    connect(ui->menu_session,&QMenu::aboutToShow,[=]{
        //刷新历史会话
        refreshHistory();
    });
}

void CMainWindow::initToolBar()
{
    m_pSessionName = new QLineEdit(this);
    m_pSessionName->setStyleSheet("QLineEdit{border:none;}");
    m_pSessionName->setPlaceholderText(tr("请输入会话名称"));
    QFocusEvent event(QEvent::FocusOut,Qt::MouseFocusReason);
    QApplication::sendEvent(m_pSessionName,&event);
    connect(m_pSessionName,&QLineEdit::editingFinished,[=]{
            qInfo()<<"会话名称:"<<"修改为:"<<m_pSessionName->text();
            if(m_pSelectedSession){
                m_pSelectedSession->name() = m_pSessionName->text();
            }
    });

    m_pNameToolBar = new QToolBar(this);
    m_pNameToolBar->addWidget(m_pSessionName);
    this->insertToolBar(ui->toolBar,m_pNameToolBar);

    //垂直
    QPushButton *pBtnV = new QPushButton(QChar(0xe679),this);
    pBtnV->setProperty("iconText",true);
    pBtnV->setToolTip(tr("垂直新建会话"));
    ui->toolBar->addWidget(pBtnV);
    connect(pBtnV,&QPushButton::clicked,[=]{
        vSplitSession("");
    });

    //水平
    QPushButton *pBtnH = new QPushButton(QChar(0xe67a),this);
    pBtnH->setProperty("iconText",true);
    pBtnH->setToolTip(tr("水平新建会话"));
    ui->toolBar->addWidget(pBtnH);
    connect(pBtnH,&QPushButton::clicked,[=]{
        hSplitSession("");
    });

    //保存会话状态
    QPushButton *pBtnSave = new QPushButton(QChar(0xe6ad),this);
    pBtnSave->setProperty("iconText",true);
    pBtnSave->setToolTip(tr("保存"));
    ui->toolBar->addWidget(pBtnSave);
    connect(pBtnSave,&QPushButton::clicked,this,&CMainWindow::slotSaveSession);

    //关闭
    QPushButton *pBtnClose = new QPushButton(QChar(0xe68e),this);
    pBtnClose->setProperty("iconText",true);
    pBtnClose->setToolTip(tr("关闭会话"));
    ui->toolBar->addWidget(pBtnClose);
    connect(pBtnClose,&QPushButton::clicked,this,&CMainWindow::slotCloseSession);

    //删除会话记录
    QPushButton *pBtnDel = new QPushButton(QChar(0xe668),this);
    pBtnDel->setProperty("iconText",true);
    pBtnDel->setToolTip(tr("删除会话，清除会话记录"));
    ui->toolBar->addWidget(pBtnDel);
    connect(pBtnDel,&QPushButton::clicked,this,&CMainWindow::slotRemoveSession);

    //置顶
    QPushButton *pBtnTop = new QPushButton(QChar(0xe6ac),this);
    pBtnTop->setProperty("iconText",true);
    pBtnTop->setCheckable(true); //@MAJR 记忆置顶状态
    pBtnTop->setToolTip(tr("窗口置顶"));
    ui->toolBar->addWidget(pBtnTop);
    connect(pBtnTop,&QPushButton::clicked,[=](bool bChecked){
        if(bChecked){
            this->setWindowFlags(this->windowFlags() | Qt::WindowStaysOnTopHint); //置顶
        }else{
            this->setWindowFlags(this->windowFlags() & ~Qt::WindowStaysOnTopHint); //取消置顶
        }
        this->show(); //应对置顶后窗口反而消失的问题
        CTableConfig::instance()->updateValue(CTableConfig::IsTop,bChecked ? "1" : "0");
    });

    //曲线设置 应仅在曲线页面显示
    QPushButton *pBtnMore = new QPushButton(QChar(0xe681),this);
    pBtnMore->setProperty("iconText",true);
    pBtnMore->setToolTip(tr("删除会话，清除会话记录"));
    ui->toolBar->addWidget(pBtnMore);
    connect(pBtnMore,&QPushButton::clicked,this,[=]{
        if(m_pSelectedSession){
            m_pSelectedSession->showChartSetting(pBtnMore->isChecked());
        }
    });

    //会话弹窗设置
    QPushButton *pBtnSessionSetting = new QPushButton(QChar(0xe689),this);
    pBtnSessionSetting->setProperty("iconText",true);
    pBtnSessionSetting->setToolTip(tr("会话设置"));
    pBtnSessionSetting->setStyleSheet("QPushButton::menu-indicator{image:none;width:0;}"); //@TODO 写入qss文件
    ui->toolBar->addWidget(pBtnSessionSetting);

    //@TODO 获取当前会话消息编码
    QMenu *pMenuCodec = new QMenu(tr("消息编码"));
    QAction *pActionUtf8 = pMenuCodec->addAction("UTF-8");
    connect(pActionUtf8,&QAction::triggered,[=]{
        pMenuCodec->setTitle(pActionUtf8->text());
        if(m_pSelectedSession){
            m_pSelectedSession->setTextCode(pActionUtf8->text());
        }
    });
    QAction *pActionGbk = pMenuCodec->addAction("GBK");
    connect(pActionGbk,&QAction::triggered,[=]{
        pMenuCodec->setTitle(pActionGbk->text());
        if(m_pSelectedSession){
            m_pSelectedSession->setTextCode(pActionGbk->text());
        }
    });

    QMenu *pMenuSetting = new QMenu(pBtnSessionSetting);
    pMenuSetting->addMenu(pMenuCodec);
    pBtnSessionSetting->setMenu(pMenuSetting);
}

void CMainWindow::initStatusBar()
{
    QStatusBar *pBar =  this->statusBar();

    if(nullptr == pBar)
        return ;

    m_pTextCodeLabel = new QLabel(pBar);

    m_pSendLabel = new QLabel(pBar);

    m_pRecvLabel = new QLabel(pBar);

    m_pBtnRecount = new QPushButton(pBar);
    m_pBtnRecount->setText(tr("重新计数"));
    connect(m_pBtnRecount,&QPushButton::clicked,[=]{
        emit sigRecount();
    });

    pBar->addPermanentWidget(m_pTextCodeLabel);
    pBar->addPermanentWidget(m_pSendLabel);
    pBar->addPermanentWidget(m_pRecvLabel);
    pBar->addPermanentWidget(m_pBtnRecount);

    slotSendBytes(0);
    slotRecvBytes(0);
    slotTextCode(CTableConfig::instance()->queryValue(CTableConfig::TextCode));
}

void CMainWindow::refreshHistory()
{
    qDebug()<<"查看历史会话..";
    //清空 原有的Action
    foreach (QAction *pAction, m_listHistory) {
            pAction->deleteLater();
    }
    m_listHistory.clear();

    qsrand(QDateTime::currentMSecsSinceEpoch());

    QVector<StSession> vecData = CTableSession::instance()->queryHistory();
    foreach (StSession session, vecData) {
        QString strColor = QColor::fromHsl(155,255,(qrand()%4+1) * 50).name();

        QAction *pActionSession = ui->menu_history->addAction(CIconFont::getInstance()->pixmap(0xe681,QSize(16,16),strColor),
                                                              session.name);
        m_listHistory.append(pActionSession);
        connect(pActionSession,&QAction::triggered,[=]{
            qInfo()<<"打开历史会话:"<<session.id<<session.name<<session.create_time;
            hSplitSession(session.id);
        });
    }
    //有历史记录  添加分隔线
    if(!m_listHistory.isEmpty()){
        QAction *pActionSepar = ui->menu_history->addSeparator();
        m_listHistory.append(pActionSepar);
    }

    //删除所有历史会话
    QAction *pActionClear = ui->menu_history->addAction(m_listHistory.isEmpty() ? tr("暂无历史") : tr("清除历史"));
    m_listHistory.append(pActionClear);
    connect(pActionClear,&QAction::triggered,[=]{
        if(!m_listHistory.isEmpty()){
            qInfo()<<"清除历史会话记录...";
            CTableSession::instance()->deleteHistory();
            refreshHistory();
        }
    });
}

void CMainWindow::slotSendBytes(int nBytes)
{
    m_pSendLabel->setText(tr("发送:") + QString::number(nBytes) + tr("字节"));
}

void CMainWindow::slotRecvBytes(int nBytes)
{
    m_pRecvLabel->setText(tr("接收:") + QString::number(nBytes) + tr("字节"));
}

void CMainWindow::slotTextCode(QString strTextCode)
{
    m_pTextCodeLabel->setText(strTextCode);
}

void CMainWindow::slotSaveSession()
{
    //保存会话状态
    if(m_pSelectedSession){
        m_pSelectedSession->saveSession();
    }
}

void CMainWindow::slotCloseSession()
{
    //关闭会话 保存写入文件
    if(m_pSelectedSession){
        m_pSelectedSession->closeSession();
    }
    qDebug()<<"close session";
    ui->page_vwindowsplitter->slotMergeScreen();
    qDebug()<<"m_pSelectedSession = nullptr";
    m_pSelectedSession = nullptr;
}

void CMainWindow::slotRemoveSession()
{
    //弹窗
    if(m_pSelectedSession){
        QString strName = m_pSelectedSession->name();
        if(QMessageBox::Ok == QMessageBox::warning(
                    this,tr("删除会话%1").arg(strName.isEmpty() ? "" : ":" + strName),QString("确定删除会话吗？"),
                    QMessageBox::Ok,QMessageBox::Cancel)){
            if(m_pSelectedSession){
                m_pSelectedSession->removeSession();
            }
            m_pSelectedSession = nullptr;
            ui->page_vwindowsplitter->slotMergeScreen();
        }
    }
}

void CMainWindow::slotShowHistory(bool bNone)
{
    if(bNone){
        ui->page_history->refreshUI();
    }
    ui->stackedWidget->setCurrentIndex(bNone ? 0 : 1);

    ui->toolBar->setHidden(bNone);
    m_pNameToolBar->setHidden(bNone);
    ui->statusbar->setHidden(bNone);
}

void CMainWindow::slotSelectSession(QString strId)
{
    //选中Id不能为空
    if(strId.isEmpty()){
        qWarning()<<"Selected id is empty!";
        return ;
    }

    //获取当前会话名称
    m_pSelectedSession = ui->page_vwindowsplitter->selectSession();
    if(m_pSelectedSession){
        m_pSessionName->setText(m_pSelectedSession->name());
        connect(m_pSelectedSession,&VSession::textCodeChanged,[=](QString strTextCode){
            this->slotTextCode(strTextCode);
        });
    }

    //更新当前选中会话
    CTableConfig::instance()->updateValue(SELECTE_ID,strId);
}

bool CMainWindow::eventFilter(QObject *watched, QEvent *event)
{
    qDebug()<<QTime::currentTime()<<"事件:"<<watched<<event;

    return QMainWindow::eventFilter(watched,event);
}
